package com.gosling.cloudspace.job;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.stream.Collectors;

/**
 * @Date: 2020/9/7 15:44
 */
@Slf4j
@Component
public class CozyDataTask {
    /**
     * 请求限制时长
     */
    public static final long requestLimit = 1 * 60 * 1000;
    /**
     * 请求数量限制
     */
    public static final long requestSumLimit = 190;
    public static final String COZY_INIT_INFO = "INFO";
    /**
     * 请求数
     */
    private static int requestSum = 0;
    private static LocalDateTime beginTime;
//    List<HotelService> hotelServiceList = new ArrayList<>();
//    private CozyTripHotelService cozyTripHotelService = new CozyTripHotelServiceImpl();
//    @Autowired
//    private HotelServiceInfoService hotelServiceInfoService;
//    @Autowired
//    private HotelServiceDataClean hotelServiceDataClean;
//    @Autowired
//    private HotelInitService hotelInitService;
//    @Autowired
//    private PlatformTransactionManager transactionManager;
//    @Autowired
//    private TransactionDefinition transactionDefinition;
//    @Autowired
//    private OperationRecordService operationRecordService;
//
//    public void execute() {
//        int totalPage = 1;
//        int pageNo = 1;
//        int pageSize = 200;
//        List<OperationRecord> operationRecords = operationRecordService.pageNotStatusByTypeAndValueType(
//                1, 1, OperationTypeEnum.COZY_HOTEL_INIT, COZY_INIT_INFO, OperationStatusEnum.COZY_HOTEL_INIT_END);
//        OperationRecord operationRecord = null;
//        CozyInitInfo cozyInitInfo = null;
//        if (operationRecords == null || operationRecords.isEmpty()) {
//            cozyInitInfo = new CozyInitInfo().setCityId(1L).setCozyCityId("1").setPageNo(pageNo).setTotalPage(totalPage);
//            operationRecord = OperationRecord.create(OperationStatusEnum.COZY_HOTEL_INIT_BEGIN, "神兽-开始拉取酒店数据")
//                    .setValueType(COZY_INIT_INFO).setValue(JSONObject.toJSONString(cozyInitInfo));
//            operationRecordService.save(operationRecord);
//        } else {
//            operationRecord = operationRecords.get(0);
//            cozyInitInfo = JSONObject.parseObject(operationRecord.getValue(), CozyInitInfo.class);
//        }
//        totalPage = cozyInitInfo.getPageNo();
//        pageNo = cozyInitInfo.getTotalPage();
//        // 查询城市:本地
//        beginTime = LocalDateTime.now();
//        log.info("神兽-开始拉取酒店数据！");
//        List<HotelCity> cityList = hotelInitService.listCityByChannelAndBeginId(HotelChannelEnum.COZY.getType(), cozyInitInfo.getCityId());
//        for (HotelCity city : cityList) {
//            if (!city.getId().equals(cozyInitInfo.getCityId())) {
//                totalPage = 1;
//                pageNo = 1;
//            }
//            log.info("拉取酒店数据-城市[id:{},name:{}]", city.getCityId(), city.getCityNameChn());
//            while (pageNo <= totalPage) {
//                {
//                    doRequestLimit();
//                }
//                cozyInitInfo.setPageNo(pageNo).setCozyCityId(city.getCityId()).setCityId(city.getId()).setTotalPage(totalPage);
//                operationRecord.setValue(JSONObject.toJSONString(cozyInitInfo)).setStatus(OperationStatusEnum.COZY_HOTEL_INIT_BEGIN.getType()).setMessage("数据初始化中……");
//                operationRecordService.update(operationRecord);
//                TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);
//                log.info("拉取酒店数据-城市[id:{},name:{}]-页码[{}]", city.getCityId(), city.getCityNameChn(), pageNo);
//                try {
//                    // 根据城市id查询酒店id集合：防止长流程中断问题，带来重复操作及数据错误问题。
//                    String searchHotelIdStr = cozyTripHotelService.searchHotelId(city.getCityId(), String.valueOf(pageNo), String.valueOf(pageSize));
//                    SearchHotelIdResponse searchHotelIdResponse = JSONObject.parseObject(searchHotelIdStr, SearchHotelIdResponse.class);
//                    totalPage = searchHotelIdResponse.getResult().getTotalCount();
//                    this.queryHotelInfo(city, searchHotelIdResponse.getResult().getItems());
//                    // 以页为单位提交事务
//                    transactionManager.commit(transaction);
//                } catch (Exception e) {
//                    String msg = e == null ? "null" : (e.getClass().getName() + "-" + e.getMessage()).substring(0, e.getMessage().length() > 254 ? 254 : e.getMessage().length());
//                    cozyInitInfo.setPageNo(pageNo).setCozyCityId(city.getCityId()).setCityId(city.getId());
//                    operationRecord.setValue(JSONObject.toJSONString(cozyInitInfo))
//                            .setStatus(OperationStatusEnum.COZY_HOTEL_INIT_FAIL.getType())
//                            .setMessage(msg);
//                    operationRecordService.update(operationRecord);
//                    // 回滚事务
//                    transaction.isRollbackOnly();
//                    log.warn("拉取酒店数据失败节点：cityId:{},cityName:{},pageNo:{},pageSize:{}", city.getCityId(), city.getCityNameChn(), pageNo, pageSize);
//                    log.error("拉取酒店数据失败！", e);
//                    return;
//                }
//                pageNo++;
//            }
//        }
//        operationRecord.setValue(JSONObject.toJSONString(cozyInitInfo)).setStatus(OperationStatusEnum.COZY_HOTEL_INIT_END.getType()).setMessage("完成");
//        operationRecordService.update(operationRecord);
//    }
//
//    private void queryHotelInfo(HotelCity city, List<HotelId> hotelIdList) {
//        if (hotelIdList == null || hotelIdList.isEmpty()) {
//            return;
//        }
//        List<HotelInfoChannel> hotelInfoChannelList = new ArrayList<>();
//        List<HotelPolicy> policies = new ArrayList<>();
//        List<HotelInfoService> hotelInfoServiceList = new ArrayList<>();
//        List<HotelPicture> hotelPictureList = new ArrayList<>();
//        hotelIdList.forEach(hotelId -> {
//            {
//                doRequestLimit();
//            }
//            this.searchHotelById(city, hotelInfoChannelList, hotelInfoServiceList, policies, hotelId.getHotelId());
//            // 图片
//            {
//                doRequestLimit();
//            }
//            String hotelImageResult = cozyTripHotelService.searchHotelImageList(hotelId.getHotelId());
//            SearchHotelImageListResponse hotelImageListResponse;
//            try {
//                hotelImageListResponse = JSONObject.parseObject(hotelImageResult, SearchHotelImageListResponse.class);
//            } catch (Exception e) {
//                log.warn("拉取图片重试！");
//                // 睡眠后，重试
//                try {
//                    Thread.sleep(requestLimit);
//                } catch (InterruptedException ex) {
//                    ex.printStackTrace();
//                }
//                String hotelImageReTryResult = cozyTripHotelService.searchHotelImageList(hotelId.getHotelId());
//                try {
//                    hotelImageListResponse = JSONObject.parseObject(hotelImageReTryResult, SearchHotelImageListResponse.class);
//                } catch (Exception exception) {
//                    // 重试失败后跳过
//                    log.warn("拉取图片重试1-[失败]-INFO[cityId:{},hotelId:{}]", city.getCityId(), hotelId);
//                    exception.printStackTrace();
//                    return;
//                }
//            }
//            if (hotelImageListResponse == null) {
//                log.warn("拉取图片重试！");
//                // 睡眠后，重试
//                try {
//                    Thread.sleep(requestLimit);
//                } catch (InterruptedException ex) {
//                    ex.printStackTrace();
//                }
//                String hotelImageReTryResult = cozyTripHotelService.searchHotelImageList(hotelId.getHotelId());
//                if (hotelImageReTryResult == null) {
//                    // 重试失败后跳过
//                    log.warn("拉取图片重试2-[失败]-INFO[cityId:{},hotelId:{}]", city.getCityId(), hotelId);
//                    return;
//                }
//                try {
//                    hotelImageListResponse = JSONObject.parseObject(hotelImageReTryResult, SearchHotelImageListResponse.class);
//                } catch (Exception exception) {
//                    // 重试失败后跳过
//                    exception.printStackTrace();
//                    log.warn("拉取图片重试21-[失败]-INFO[cityId:{},hotelId:{}]", city.getCityId(), hotelId);
//                    return;
//                }
//            }
//            List<ImageList> hotelImageList = hotelImageListResponse.getResult();
//            if (hotelImageList != null && !hotelImageList.isEmpty()) {
//                hotelImageList.forEach(imgObject -> {
//                    hotelPictureList.add(new HotelPicture()
//                            .setHotelSn(String.valueOf(hotelId.getHotelId()))
//                            .setPicUrl(imgObject.getImageUrl())
//                            .setChannelCode(HotelChannelEnum.COZY.getType())
//                            .setPicType(imgObject.getImageType()));
//                });
//            }
//
//        });
//        // 持久化：批量存储
//        hotelInitService.saveBatchHotelInfoChannelByCozy(hotelInfoChannelList);
//        hotelInitService.saveBatchPolicyByCozy(policies);
//        hotelInitService.saveBatchHotelInfoServiceByCozy(hotelInfoServiceList);
//        hotelInitService.saveBatchPictureByCozy(hotelPictureList);
//    }
//
//    private void searchHotelById(HotelCity city, List<HotelInfoChannel> hotelInfoChannelList, List<HotelInfoService> hotelInfoServiceList, List<HotelPolicy> policies, String hotelId) {
//
//        // 查询数据：通过入住时间查询:原因是因为，此查询结果数据完整性更好。
//        SearchHotelDetailResponse searchHotelDetailResponse = cozyTripHotelService.searchHotelDetail(
//                hotelId, LocalDate.now().toString(), LocalDate.now().plusDays(1).toString(), city.getCityId());
//        if (searchHotelDetailResponse == null) {
//            try {
//                // 睡眠后，重试
//                Thread.sleep(requestLimit);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            searchHotelDetailResponse = cozyTripHotelService.searchHotelDetail(
//                    hotelId, LocalDate.now().toString(), LocalDate.now().plusDays(1).toString(), city.getCityId());
//        }
//        if (searchHotelDetailResponse == null) {
//            log.warn("拉取酒店重试-[失败]-INFO[cityId:{},hotelId:{}]", city.getCityId(), hotelId);
//            return;
//        }
//        HotelEntity hotel = searchHotelDetailResponse.getResult();
//        if (hotel == null) {
//            log.warn("未查询到酒店信息[hotelId:{}]", hotelId);
//            return;
//        }
//        Point point2 = PointTransfer.baidu2AMap(hotel.getLongitude(), hotel.getLatitude());
//        // 转换
//        HotelInfoChannel infoChannel = new HotelInfoChannel()
//                .setHotelName(hotel.getHotelName() == null ? "" : hotel.getHotelName())
//                .setHotelNameEn(hotel.getHotelNameEN())
//                // 城市id统一使用sys_city中的数据，所以此处需要进行查询
//                .setCityId(city.getCityId())
//                .setCityName(city.getCityNameChn())
//                .setAddress(hotel.getAddressLine() == null ? "" : hotel.getAddressLine())
//                .setAddressEng("")
//                .setLongitude(String.valueOf(point2.getLongitude()))
//                .setLatitude(String.valueOf(point2.getLatitude()))
//                .setStarRate(BigDecimal.valueOf(hotel.getHotelStarLicence()))
//                .setStarLicence(hotel.getHotelStarRate().intValue() > 5 ? 5 : hotel.getHotelStarRate().intValue())
//                .setFirstPicUrl(hotel.getFirstImg() == null ? "" : hotel.getFirstImg())
//                .setCityCode(hotel.getThreeCode() == null ? "" : hotel.getThreeCode())
//                .setServiceCode(null)
//                .setDescription(hotel.getDescription() == null ? "" : hotel.getDescription())
//                .setChannelCode(HotelChannelEnum.COZY.getType())
//                .setHotelSn(hotel.getSourceHotelCode() == null ? hotelId : hotel.getSourceHotelCode())
//                .setUserRate(BigDecimal.valueOf(hotel.getCtripUserRate()))
//                .setMinPrice(BigDecimal.valueOf(hotel.getMinPrice()))
//                .setRoadCross(hotel.getRoadCross() == null ? "" : hotel.getRoadCross())
//                .setBrandId(0)
//                .setRoomNum(hotel.getRoomquantity())
//                .setScenicId(0)
//                .setMetroId(0)
//                .setBusStationId(0)
//                .setZoneId(0)
//                .setTrainStationId(0)
//                .setMinPrice(BigDecimal.valueOf(hotel.getMinPrice() == null ? 0 : hotel.getMinPrice()))
//                .setTelephone("")
//                .setInvoiceType(0)
//                .setTelephone(hotel.getMobile() == null ? "" : hotel.getMobile());
//
//        if (hotelServiceList.isEmpty()) {
//            // 查询列表
//            hotelServiceList = hotelServiceInfoService.queryALLServiceAndFacility();
//        }
//        // 设施设备
//        List<HotelService> services = new ArrayList<>();
//        if (hotel.getServiceName() != null) {
//            String[] split;
//            split = hotel.getServiceName().split(",");
//            if (hotel.getServiceName().contains("、")) {
//                split = hotel.getServiceName().split("、");
//            }
//            for (String s : split) {
//                Facility facility = new Facility();
//                facility.setNameChn(s);
//                Optional<HotelService> first = hotelServiceList.stream().filter(service -> service.getName().equals(s)).findFirst();
//                // 如果存在则存到list中,如果不存在就按照规则生成一条数据进行存储
//                if (first.isPresent()) {
//                    HotelService hotelService = first.get();
//                    services.add(hotelService);
//                } else {
//                    HotelServiceOrPolicyValue hotelServiceOrPolicyValue = hotelServiceDataClean.setServiceType(facility);
//                    if (hotelServiceOrPolicyValue.getIsService()) {
//                        // 先生成数据，
//                        HotelService hotelService = new HotelService()
//                                .setType(hotelServiceOrPolicyValue.getType())
//                                .setMajorType(hotelServiceOrPolicyValue.getMajorType())
//                                .setName(s)
//                                .setNameEng("")
//                                .setRemark("")
//                                .setCode("");
//                        // 存储，
//                        hotelServiceInfoService.save(hotelService);
//                        // 再add到集合中
//                        services.add(hotelService);
//                        hotelServiceList.add(hotelService);
//                    }
//                }
//            }
//        }
//        // 政策
//        hotel.getPolicy().forEach(policy -> {
//            HotelPolicy hotelPolicy = new HotelPolicy()
//                    .setHotelSn(infoChannel.getHotelSn())
//                    .setContent(policy.getPolicyText())
//                    .setChannelCode(HotelChannelEnum.COZY.getType())
//                    .setName(policy.getPloicyName());
//            policies.add(hotelPolicy);
//        });
//        policies.add(new HotelPolicy().setHotelSn(infoChannel.getHotelSn()).setChannelCode(HotelChannelEnum.COZY.getType()).setName("入住时间").setContent(hotel.getCheckInTime()));
//        policies.add(new HotelPolicy().setHotelSn(infoChannel.getHotelSn()).setChannelCode(HotelChannelEnum.COZY.getType()).setName("离店时间").setContent(hotel.getCheckOutTime()));
//        String serviceIds = services.stream().map(HotelService::getIdStr).collect(Collectors.joining(","));
//        infoChannel.setServiceCode(serviceIds);
//        services.forEach(s -> hotelInfoServiceList.add(new HotelInfoService()
//                .setChannelCode(HotelChannelEnum.COZY.getType())
//                .setHotelServiceid(s.getId())
//                .setHotelSn(hotelId)));
//
//        // 渠道酒店信息
//        hotelInfoChannelList.add(infoChannel);
//    }
//
//    /**
//     * 获取增量
//     */
//    public void queryHotelIdByUpdateTime() {
//        beginTime = LocalDateTime.now();
//        Date today = new Date();
//        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
//        String strDate = formatter.format(today);
//        HotelIdByUpdateTimeModel model = new HotelIdByUpdateTimeModel();
//        model.setPageNo(1);
//        model.setPageSize(20);
//        model.setTimetype("TenMinutes");
//        model.setUpdatTime("2018-08-20");
//        log.info("神兽-开始增量拉取酒店数据！");
//        String searchHotelIdStr = cozyTripHotelService.queryHotelIdByUpdateTime(String.valueOf(model.getPageNo()), String.valueOf(model.getPageSize()), model.getUpdatTime(), model.getTimetype());
//        log.info("神兽-开始增量拉取酒店数据！{}", searchHotelIdStr);
//        HotelIdByUpdateTimeResponse response = JSONObject.parseObject(searchHotelIdStr, HotelIdByUpdateTimeResponse.class);
////            log.info("拉取酒店数据-城市{}", city.getCityNameChn());
////            while (pageNo <= totalPage) {
////                {
////                    doRequestLimit();
////                }
////                // 根据城市id查询酒店id集合：防止长流程中断问题，带来重复操作及数据错误问题。
////                String searchHotelIdStr = cozyTripHotelService.searchHotelId(city.getCityId(), String.valueOf(pageNo), String.valueOf(pageSize));
////                SearchHotelIdResponse searchHotelIdResponse = JSONObject.parseObject(searchHotelIdStr, SearchHotelIdResponse.class);
////                totalPage = searchHotelIdResponse.getResult().getTotalCount();
////                this.queryHotelInfo(searchHotelIdResponse.getResult().getItems());
////                pageNo++;
////            }
//    }


    /**
     * 请求限制处理
     */
    private void doRequestLimit() {
        // 60秒钟200个请求处理
        // 判断开始时间到现在过去了多长时间，是否超过1分钟
        Duration duration = Duration.between(beginTime, LocalDateTime.now());
        boolean isLimit = duration.toMillis() <= requestLimit && requestSum >= requestSumLimit;
        if (isLimit) {
            try {
                log.warn("请求达到限制，线程睡眠！");
                Thread.sleep(requestLimit - duration.toMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            requestSum = 0;
            beginTime = LocalDateTime.now();
        }
        requestSum++;
    }
}
